import Player from '../entity/Player';
import PlayerService from '../service/PlayerService';
import { observable } from '@ohos:rxjs';

/**
 * 玩家视图模型类
 * 负责连接服务层和界面层，处理数据绑定和用户交互
 */
export default class PlayerViewModel {
  private playerService: PlayerService;
  private currentPlayer: Player | null = null;
  // 使用可观察对象实现数据绑定
  public playerData = observable({} as Player);
  public isLoading: boolean = false;
  public errorMessage: string = '';
  // 玩家列表数据
  public playerList = observable([] as Player[]);

  constructor() {
    this.playerService = PlayerService.getInstance();
  }

  /**
   * 初始化玩家视图模型
   */
  async initialize(): Promise<void> {
    this.isLoading = true;
    this.clearErrorMessage();
    try {
      // 并行加载默认玩家和玩家列表，提高初始化效率
      await Promise.all([
        this.loadDefaultPlayer(),
        this.refreshPlayerList()
      ]);
    } catch (error) {
      this.setErrorMessage('初始化失败', error as Error);
    } finally {
      this.isLoading = false;
    }
  }

  /**
   * 创建新玩家
   * @param name 玩家名称
   * @returns 是否创建成功
   */
  async createNewPlayer(name: string): Promise<boolean> {
    // 参数验证
    if (!name || name.trim().length === 0) {
      this.setErrorMessage('玩家名称不能为空');
      return false;
    }

    this.isLoading = true;
    this.clearErrorMessage();
    try {
      const player = await this.playerService.createPlayer(name.trim());
      this.setCurrentPlayer(player);
      // 更新玩家列表
      await this.refreshPlayerList();
      return true;
    } catch (error) {
      this.setErrorMessage('创建玩家失败', error as Error);
      return false;
    } finally {
      this.isLoading = false;
    }
  }

  /**
   * 加载玩家数据
   * @param playerId 玩家ID
   * @returns 是否加载成功
   */
  async loadPlayer(playerId: string): Promise<boolean> {
    // 参数验证
    if (!playerId) {
      this.setErrorMessage('玩家ID不能为空');
      return false;
    }

    this.isLoading = true;
    this.clearErrorMessage();
    try {
      const player = await this.playerService.getPlayerById(playerId);
      if (player) {
        this.setCurrentPlayer(player);
        return true;
      } else {
        this.setErrorMessage('玩家不存在');
        return false;
      }
    } catch (error) {
      this.setErrorMessage('加载玩家数据失败', error as Error);
      return false;
    } finally {
      this.isLoading = false;
    }
  }

  /**
   * 加载默认玩家
   */
  private async loadDefaultPlayer(): Promise<void> {
    try {
      // 优先从本地存储中获取最近使用的玩家ID
      const recentPlayerId = this.getRecentPlayerId();
      
      if (recentPlayerId) {
        const player = await this.playerService.getPlayerById(recentPlayerId);
        if (player) {
          this.setCurrentPlayer(player);
          return;
        }
      }
      
      // 如果没有最近使用的玩家或玩家不存在，则加载第一个玩家
      const players = await this.playerService.getAllPlayers();
      if (players.length > 0) {
        this.setCurrentPlayer(players[0]);
      }
    } catch (error) {
      console.warn('加载默认玩家失败:', error);
    }
  }
  
  /**
   * 获取最近使用的玩家ID
   * @returns 玩家ID或null
   */
  private getRecentPlayerId(): string | null {
    try {
      // 这里可以实现从本地存储获取最近使用的玩家ID的逻辑
      // 例如使用@ohos:data.storage等API
      return null;
    } catch (error) {
      console.warn('获取最近使用的玩家ID失败:', error);
      return null;
    }
  }
  
  /**
   * 保存最近使用的玩家ID
   * @param playerId 玩家ID
   */
  private saveRecentPlayerId(playerId: string): void {
    try {
      // 这里可以实现将最近使用的玩家ID保存到本地存储的逻辑
      // 例如使用@ohos:data.storage等API
    } catch (error) {
      console.warn('保存最近使用的玩家ID失败:', error);
    }
  }

  /**
   * 设置当前玩家并更新可观察的数据
   * @param player 玩家对象
   */
  private setCurrentPlayer(player: Player): void {
    this.currentPlayer = player;
    // 保存最近使用的玩家ID
    this.saveRecentPlayerId(player.id);
    // 更新可观察数据，实现双向绑定
    Object.assign(this.playerData, player.toJSON());
  }

  /**
   * 更新玩家信息
   * @param updates 要更新的字段
   * @returns 是否更新成功
   */
  async updatePlayer(updates: Partial<Player>): Promise<boolean> {
    if (!this.currentPlayer) {
      this.setErrorMessage('没有选中的玩家');
      return false;
    }

    // 参数验证
    if (!updates || Object.keys(updates).length === 0) {
      return true; // 没有要更新的字段，直接返回成功
    }

    this.isLoading = true;
    this.clearErrorMessage();
    try {
      // 创建更新后的玩家对象副本，避免直接修改当前对象
      const updatedPlayer = { ...this.currentPlayer, ...updates };
      // 保存到服务层
      await this.playerService.updatePlayer(updatedPlayer);
      // 更新当前玩家和视图数据
      this.setCurrentPlayer(updatedPlayer);
      return true;
    } catch (error) {
      this.setErrorMessage('更新玩家信息失败', error as Error);
      return false;
    } finally {
      this.isLoading = false;
    }
  }

  /**
   * 增加玩家经验值
   * @param amount 经验值数量
   * @returns 是否增加成功
   */
  async addPlayerExperience(amount: number): Promise<boolean> {
    if (!this.currentPlayer) {
      this.setErrorMessage('没有选中的玩家');
      return false;
    }

    // 参数验证
    if (isNaN(amount) || amount <= 0) {
      this.setErrorMessage('经验值必须是正数');
      return false;
    }

    this.isLoading = true;
    this.clearErrorMessage();
    try {
      await this.playerService.addPlayerExperience(this.currentPlayer.id, amount);
      // 重新加载更新后的玩家数据
      await this.loadPlayer(this.currentPlayer.id);
      return true;
    } catch (error) {
      this.setErrorMessage('增加经验值失败', error as Error);
      return false;
    } finally {
      this.isLoading = false;
    }
  }

  /**
   * 完成案件并获得奖励
   * @param caseId 案件ID
   * @param score 获得的分数
   * @returns 是否完成成功
   */
  async completeCase(caseId: string, score: number): Promise<boolean> {
    if (!this.currentPlayer) {
      this.setErrorMessage('没有选中的玩家');
      return false;
    }

    // 参数验证
    if (!caseId || caseId.trim().length === 0) {
      this.setErrorMessage('案件ID不能为空');
      return false;
    }
    if (isNaN(score) || score < 0) {
      this.setErrorMessage('分数必须是非负数');
      return false;
    }

    this.isLoading = true;
    this.clearErrorMessage();
    try {
      await this.playerService.completeCase(this.currentPlayer.id, caseId.trim(), score);
      // 重新加载更新后的玩家数据
      await this.loadPlayer(this.currentPlayer.id);
      return true;
    } catch (error) {
      this.setErrorMessage('完成案件失败', error as Error);
      return false;
    } finally {
      this.isLoading = false;
    }
  }

  /**
   * 收集线索
   * @param clueId 线索ID
   * @returns 是否收集成功
   */
  async collectClue(clueId: string): Promise<boolean> {
    if (!this.currentPlayer) {
      this.setErrorMessage('没有选中的玩家');
      return false;
    }

    // 参数验证
    if (!clueId || clueId.trim().length === 0) {
      this.setErrorMessage('线索ID不能为空');
      return false;
    }

    this.isLoading = true;
    this.clearErrorMessage();
    try {
      await this.playerService.collectClue(this.currentPlayer.id, clueId.trim());
      // 重新加载更新后的玩家数据
      await this.loadPlayer(this.currentPlayer.id);
      return true;
    } catch (error) {
      this.setErrorMessage('收集线索失败', error as Error);
      return false;
    } finally {
      this.isLoading = false;
    }
  }

  /**
   * 获取所有玩家列表
   * @returns 玩家列表
   */
  async getAllPlayers(): Promise<Player[]> {
    return await this.playerService.getAllPlayers();
  }
  
  /**
   * 刷新玩家列表
   */
  async refreshPlayerList(): Promise<void> {
    this.isLoading = true;
    this.clearErrorMessage();
    try {
      const players = await this.playerService.getAllPlayers();
      // 更新可观察的玩家列表
      this.playerList.length = 0; // 清空现有列表
      players.forEach(player => {
        this.playerList.push(player);
      });
    } catch (error) {
      this.setErrorMessage('获取玩家列表失败', error as Error);
    } finally {
      this.isLoading = false;
    }
  }

  /**
   * 清除当前错误信息
   */
  clearErrorMessage(): void {
    this.errorMessage = '';
  }
  
  /**
   * 设置错误信息
   * @param message 错误消息
   * @param error 错误对象（可选）
   */
  private setErrorMessage(message: string, error?: Error): void {
    this.errorMessage = message;
    if (error) {
      console.error(`${message}:`, error);
      // 在开发环境下可以显示详细错误信息
      if (process.env.NODE_ENV === 'development') {
        this.errorMessage += `: ${error.message}`;
      }
    }
  }

  /**
   * 获取当前玩家的进度信息
   * @returns 进度信息对象
   */
  getPlayerProgress(): { casesSolved: number; totalCases: number; progressPercentage: number } {
    if (!this.currentPlayer) {
      return { casesSolved: 0, totalCases: 0, progressPercentage: 0 };
    }

    // 这里假设有10个案件作为总数，实际项目中可能需要从配置或其他地方获取
    const totalCases = 10;
    const casesSolved = this.currentPlayer.casesSolved?.length || 0;
    const progressPercentage = totalCases > 0 ? (casesSolved / totalCases) * 100 : 0;

    return {
      casesSolved,
      totalCases,
      progressPercentage: Math.round(progressPercentage)
    };
  }
  
  /**
   * 获取当前玩家
   * @returns 当前玩家或null
   */
  getCurrentPlayer(): Player | null {
    return this.currentPlayer;
  }
  
  /**
   * 检查玩家是否已加载
   * @returns 是否已加载玩家
   */
  isPlayerLoaded(): boolean {
    return this.currentPlayer !== null;
  }
}